package crp.core.security.domain.services;

import com.qwlabs.lang.C2;
import crp.core.security.domain.messages.SecurityMessages;
import crp.core.security.domain.models.AuthorizeCommand;
import crp.core.security.domain.models.RoleEntity;
import crp.core.user.domain.models.UserEntity;
import crp.core.security.domain.models.UserRoleEntity;
import crp.core.security.domain.repositories.RoleRepository;
import crp.core.user.domain.repositories.UserRepository;
import crp.core.security.domain.repositories.UserRoleRepository;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.List;
import java.util.Set;

@ApplicationScoped
public class UserAuthorizer {
    private final UserRepository userRepository;
    private final RoleRepository roleRepository;
    private final UserRoleRepository userRoleRepository;

    @Inject
    public UserAuthorizer(UserRepository userRepository,
                          RoleRepository roleRepository,
                          UserRoleRepository userRoleRepository) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.userRoleRepository = userRoleRepository;
    }

    public AuthorizeCommand createCommand(String userId, Set<String> roleIds) {
        UserEntity user = userRepository.findByIdOptional(userId)
                .orElseThrow(() -> SecurityMessages.INSTANCE.userNotFound(userId));
        List<RoleEntity> roles = C2.list(roleRepository.findByIds(roleIds));
        return new AuthorizeCommand(user, roles);
    }

    public void authorize(AuthorizeCommand command) {
        userRoleRepository.deleteByUser(command.getUser());
        command.getRoles().forEach(role -> {
            UserRoleEntity userRole = new UserRoleEntity();
            userRole.setUser(command.getUser());
            userRole.setRole(role);
            userRoleRepository.persist(userRole);
        });
    }
}
